#define MSPPPOE_C
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//set start flag
#include <libmscommon/mscommon.h>
#include <libmscommon/mstime.h>
#include <libmscommon/msnetwork.h>
#include <libmscommon/msmd.h>
#include <libmscommon/mscjson.h>
#include <libmscommon/msthread.h>
#include <libmscommon/msstring.h>
#include <libmslog/mslog.h>
#include "mspppoe.h"
#include "msperformance.h"

#define STRING_PPPD_PID		"/var/run/ppp%d.pid"
#define STRING_PIDFILE_PPPD	"/var/run/pppoe_%s.pid.pppd"

#define FLAG "PPPOE"
#define mspppoe_tools 		"mscore_pppoe"

#define mspppoe_setup		"mspppoe_setup"
#define mspppoe_start		"mspppoe_start"
#define mspppoe_stop 		"mspppoe_stop"

#define ms_dbmspppoe  	"/etc/mscore/db/msdb_mspppoe.db"

static NETCARDInfo*pnetcard_info=&hardware_info.netcard_info;

typedef struct MSPPPOEMONITORContext{
	MSTHREADContext msst_ppprecovery;
	MSTHREADContext msst_pppupdate;
} MSPPPOEMONITORContext;

ETHPPPContext ethnppp_ctt;		//realtime data
ETHPPPContext ethnppp_ctt_db;	//database use to recovery pppoe config

MSPPPOEMONITORContext mspppoemonitor_ctt;

static ms_void mspppoe_innerapi_updateFlag(ms_string ms_in ethn_name,ms_bool used)
{
	if(ms_buflen(ethn_name)>0){
		ms_u08 netcard_index=0;
		for(netcard_index=0;netcard_index<pnetcard_info->num;netcard_index++){
			if(ms_strncmp_saeq(pnetcard_info->cfg_info[netcard_index].name, ethn_name)){
				pnetcard_info->cfg_info[netcard_index].use_pppoe=used;
				break;
			}
		}
	}
}
static ms_u08 mspppoe_innerapi_pppNum(ms_void)
{
#if defined(OS_LINUX_SOC)
	ms_byte buf[20480]={0};
	ms_s32 len = fread(buf, ms_bufsize(ms_byte), ms_bufsize(buf), msfp_netdev);
	fseek( msfp_netdev, 0, SEEK_SET );
	if (len<0){
		ms_errRet(-1,"Read /proc/net/dev  failed");
	}
	
	ms_string str_array_ret[256];
	ms_s32 item_num=msstr_api_split(buf, "\n", str_array_ret);
	ms_u08 ppp_num=0;
	ms_u08 eth_index=2;
	for(eth_index=2;eth_index<item_num;eth_index++){
		ms_string str_array[256];
		msstr_api_split(str_array_ret[eth_index], ":", str_array);
		int char_index=0;
		int temp_inde=0;
		for(char_index=0;char_index<strlen(str_array[0]);char_index++){
			if(32!=str_array[0][char_index]){
				if(ms_strncmp_seq(&str_array[0][char_index], "ppp")){
					ppp_num+=1;
					break;
				}
				break;
			}
		}
	}	
#else
	ms_funcNosupports;
#endif
	return ppp_num;
}
static ms_void mspppoe_innerapi_envClear(ms_void)
{
	ETHPPPContext *pethnppp_ctt=&ethnppp_ctt;
	char eth_index=0;
	for(eth_index=0;eth_index<MAXNUM_ETH;eth_index++){
		ETHNInfo*pethn_info=&pethnppp_ctt->ethn_info[eth_index];
		if(ms_true==pethn_info->is_setup
			&&ms_true==pethn_info->is_connect){
			ms_byte cmdbuf[256]={0};
			ms_cmd(cmdbuf,"%s %s",mspppoe_stop,pethn_info->pppoe_param.ethn_name);
			ms_buf0(pethn_info->time_string);
		}
	}
	ms_cmdKill("pgrep ppp");
	//must remove those files,otherwise mspppoe_innerapi_recovrystart maybe lose
	ms_system("rm /var/run/ppp*.pid  -fr");
	ms_system("rm /var/run/pppoe_*  -fr");
}
static ms_void mspppoe_innerapi_rmPidFile(ms_string ms_in ethn_name)
{
	ms_pamcheck( ethn_name, "ethn_name");
	ms_byte cmdbuf[512]={0};
	ms_cmd(cmdbuf, "rm /var/run/pppoe_%s.pid*  -fr ", ethn_name);
}
ms_bool mspppoe_innerapi_check(ETHNInfo* ms_io pethn_info)
{
	ms_pamcheckRet( ms_false,pethn_info, "pethn_info");
	ms_byte filename_pidpppd[256]={0};
	ms_sprintfs(filename_pidpppd,STRING_PIDFILE_PPPD,pethn_info->pppoe_param.ethn_name);
	ms_byte pppdpid_buf[128]={0};
	ms_u32 pppd_pid=0;
	if(msmd_api_read(filename_pidpppd,pppdpid_buf,sizeof(pppdpid_buf)) > 0){
		pppd_pid=ms_atoi(pppdpid_buf);
		//ms_debug("[%s] %s is %d", pethn_info->pppoe_param.ethn_name,filename_pidpppd,pppd_pid)
		ms_u08 index=0;
		for(index=0;index<MAXNUM_ETH;index++){
			ms_sprintfs(filename_pidpppd,STRING_PPPD_PID,index);
			if(msmd_api_read(filename_pidpppd,pppdpid_buf,sizeof(pppdpid_buf))>0){
				//ms_debug("[%s] %s is %d", pethn_info->pppoe_param.ethn_name,pppdpid_buf,pppd_pid)
				if(pppd_pid==ms_atoi(pppdpid_buf)){
					ms_sprintfs(pethn_info->ppp_info.name,"ppp%d",index);
					//return  (msnet_api_getIfaceIp(pethn_info->ppp_info.name,pethn_info->ppp_info.ipaddress)<0) ? ms_false : ms_true;
				#if 0	
					return (2==msnet_api_getIfaceIpMask(pethn_info->ppp_info.name,pethn_info->ppp_info.ipaddress,pethn_info->ppp_info.netmask))? ms_false : ms_true;
				#else
					if(0==msnet_api_getIfaceIpMask(pethn_info->ppp_info.name,pethn_info->ppp_info.ipaddress,pethn_info->ppp_info.netmask)){
						if(ms_buflen(pethn_info->ipaddr_testing)>0
							&& ms_strncmp_sneq(pethn_info->ipaddr_testing, "none")){
							return msnet_api_isReachable(pethn_info->ipaddr_testing,80);
						}else{
							return ms_true;
						}
					}else{
						return ms_false;
					}
				#endif
				}
			}
		}
	}
	return ms_false;
}

ms_s08 mspppoe_innerapi_getPppInfo(ETHNInfo* ms_io pethn_info)
{
	ms_pamcheckRet( ms_false,pethn_info, "pethn_info");
	ms_sleep(3);
	char index=0;
	char pidfile_pppd[256]={0};
	ms_sprintfs(pidfile_pppd,STRING_PIDFILE_PPPD,pethn_info->pppoe_param.ethn_name);
	unsigned char pppdpid_buf[128]={0};
	unsigned int pppd_pid=0;
	if(msmd_api_read(pidfile_pppd,pppdpid_buf,sizeof(pppdpid_buf))>0){
		pppd_pid=atoi(pppdpid_buf);
		//ms_more("[%s] %s  is %d", pethn_info->pppoe_param.ethn_name,pidfile_pppd,atoi(pppdpid_buf))
		for(index=0;index<7;index++){
			char index_ppp=0;
			for(index_ppp=0;index_ppp<MAXNUM_ETH;index_ppp++){
				ms_sprintfs(pidfile_pppd,STRING_PPPD_PID,index_ppp);
				if(msmd_api_read(pidfile_pppd,pppdpid_buf,sizeof(pppdpid_buf))>0){
					ms_more("[%s] %s is %d", pethn_info->pppoe_param.ethn_name,pidfile_pppd,ms_atoi(pppdpid_buf))
					if(pppd_pid==ms_atoi(pppdpid_buf)){
						ms_sprintfs(pethn_info->ppp_info.name,"ppp%d",index_ppp);
						//return (msnet_api_getIfaceIp(pethn_info->ppp_info.name,pethn_info->ppp_info.ipaddress) <0 ) ? 0 : 1;
						if(0==msnet_api_getIfaceIpMask(pethn_info->ppp_info.name,pethn_info->ppp_info.ipaddress,pethn_info->ppp_info.netmask)){
							if(ms_buflen(pethn_info->ipaddr_testing)>0
								&& ms_strncmp_sneq(pethn_info->ipaddr_testing, "none")){
								return msnet_api_isReachable(pethn_info->ipaddr_testing,80);
							}else{
								return ms_true;
							}
						}else{
							return ms_false;
						}
					}
				}
			}
			ms_sleep(1);
		}
	}
	return 2;
}
ms_void mspppoe_innerapi_recovrystart(ms_void)
{
	ETHPPPContext *pethnppp_ctt=&ethnppp_ctt;
	char eth_index=0;
	for(eth_index=0;eth_index<MAXNUM_ETH;eth_index++){
		ETHNInfo*pethn_info=&pethnppp_ctt->ethn_info[eth_index];
		if(ms_true==pethn_info->is_setup
			&&ms_true==pethn_info->is_connect){
			mspppoe_innerapi_updateFlag(pethn_info->pppoe_param.ethn_name,ms_true);
			//check the if the iface is pppoe 
			if(ms_false==mspppoe_innerapi_check(pethn_info)){
				ms_byte cmdbuf[256]={0};
				ms_cmd(cmdbuf,"%s %s",mspppoe_stop,pethn_info->pppoe_param.ethn_name);
				ms_sprintfs(cmdbuf,"%s %s",mspppoe_start,pethn_info->pppoe_param.ethn_name);
				if(ms_false==ms_cmdRet(cmdbuf)){
					pethn_info->is_connect=ms_false;	
					ms_buf0(pethn_info->time_string);
				}else{
					pethn_info->is_connect=ms_true;
					//Get the pppx info and bind with iface
					if(1!=mspppoe_innerapi_getPppInfo(pethn_info)){
						pethn_info->is_connect=ms_false;
						ms_buf0(pethn_info->time_string);
						ms_errNoret("[%s]mspppoe_innerapi_getPppInfo failed",pethn_info->pppoe_param.ethn_name);
					}else{
						ms_s08 strCurDTime[64]={0};
						ms_strcpy(pethn_info->time_string, mstime_api_curDTime(mstime_fmt_datetime,strCurDTime));
					}
				}
			}
		}else{
			mspppoe_innerapi_updateFlag(pethn_info->pppoe_param.ethn_name,ms_false);
		}
	}
}

ETHNInfo *mspppoe_innerapi_getValidEthn(ms_string ms_in ethn_name,ETHPPPContext * ms_io pethnppp_ctt)
{
	ms_pamcheckRet( ms_null,ethn_name, "ethn_name");
	ETHNInfo *pethn_info=mspppoe_api_matchEthn(ethn_name,pethnppp_ctt);
	if(ms_null!=pethn_info){
		ms_waring("[%s]no need to get valid ethn",ethn_name);
		return pethn_info;
	}
	char eth_index=0;
	for(eth_index=0;eth_index<MAXNUM_ETH;eth_index++){
		pethn_info=&pethnppp_ctt->ethn_info[eth_index];
		if(0==pethn_info->is_setup){
			return pethn_info;
		}
	}
	return ms_null;
}

static ms_s08 mspppoe_innerapi_readDB(ETHPPPContext *pethnppp_ctt)
{
	ms_bufcheckRet(-1, pethnppp_ctt);
	ms_byte json_buf[40960]={0};
	if(0>msmd_api_read2(ms_dbmspppoe, json_buf, sizeof(json_buf))){
		ms_errRet(-1,"msmd_api_read2 faild");
	}
	cJSON *jsonroot = cJSON_Parse(json_buf);
	if(!jsonroot) {
		ms_errRet(-1,"cJSON_Parse:get root faild");
	}

	cJSON *json_mspppoeinfo_array=cJSON_GetObjectItem(jsonroot,"mspppoeinfo");
	int arrySize=cJSON_GetArraySize(json_mspppoeinfo_array); 
	cJSON *json_mspppoeinfo_list=json_mspppoeinfo_array->child;
	int eth_index=0;
	cJSON *js_item=ms_null;
	int ret=0;
	while(json_mspppoeinfo_list!=ms_null)  {  
		ETHNInfo *pethn_info=&pethnppp_ctt->ethn_info[eth_index];
		MSJSON_PARSE_STRING(js_item, json_mspppoeinfo_list, "ethn_name", pethn_info->pppoe_param.ethn_name);
		MSJSON_PARSE_STRING(js_item, json_mspppoeinfo_list, "username", pethn_info->pppoe_param.username);	
		MSJSON_PARSE_STRING(js_item, json_mspppoeinfo_list, "userpasswd", pethn_info->pppoe_param.userpasswd);
		MSJSON_PARSE_STRING(js_item, json_mspppoeinfo_list, "demond", pethn_info->pppoe_param.demond);
		MSJSON_PARSE_STRING(js_item, json_mspppoeinfo_list, "firewall", pethn_info->pppoe_param.firewall);
		MSJSON_PARSE_STRING(js_item, json_mspppoeinfo_list, "dns1", pethn_info->pppoe_param.dns1);
		MSJSON_PARSE_STRING(js_item, json_mspppoeinfo_list, "dns2", pethn_info->pppoe_param.dns2);
		MSJSON_PARSE_INT(js_item, json_mspppoeinfo_list, "is_setup", pethn_info->is_setup);
		MSJSON_PARSE_INT(js_item, json_mspppoeinfo_list, "is_connect", pethn_info->is_connect);
		MSJSON_PARSE_STRING(js_item, json_mspppoeinfo_list, "ipaddr_testing", pethn_info->ipaddr_testing);
		eth_index++;
		json_mspppoeinfo_list=json_mspppoeinfo_list->next; 
	}  
	return 0;
}

ms_void * mspppoe_innerapi_update(ms_void * arglist)
{
	msthread_api_setName("pppoeUpdate");
	while (1){
		if(ms_true==ethnppp_ctt.init){
			int eth_index=0;
			for(eth_index=0;eth_index<MAXNUM_ETH;eth_index++){
				ETHNInfo *pethn_info=&ethnppp_ctt.ethn_info[eth_index];
				ETHNInfo *pethndb_info=&ethnppp_ctt_db.ethn_info[eth_index];
				if(ms_buflen(pethn_info->pppoe_param.ethn_name)>0
					&(ms_true==pethndb_info->is_setup)
					&(ms_true==pethndb_info->is_connect)){
					ms_more("[status]%s:----is_setup:%d-is_connect:%d",pethn_info->pppoe_param.ethn_name,pethn_info->is_setup,pethn_info->is_connect);
					ms_s08 ret=mspppoe_innerapi_getPppInfo(pethn_info);
					ms_more("[status]%s:----mspppoe_innerapi_getPppInfo:%d(1-connect)",pethn_info->pppoe_param.ethn_name,ret);
					switch(ret){
						case 2:
							if(ms_true==pethn_info->is_connect){
								ms_buf0(pethn_info->time_string);
							}
							pethn_info->is_connect=ms_false;
							break;
						case 0:
							if((ms_buflen(pethn_info->pppoe_param.ethn_name)>0)
								&&(ms_true==pethn_info->is_connect)){
								ms_debug("[status]----mspppoe_innerapi_rmPidFile");
								ms_byte cmdbuf[256]={0};
								//mspppoe_innerapi_rmPidFile(pethn_info->pppoe_param.ethn_name);
								ms_cmd(cmdbuf,"%s %s",mspppoe_stop,pethn_info->pppoe_param.ethn_name);
							}
							if(ms_true==pethn_info->is_connect){
								ms_buf0(pethn_info->time_string);
							}
							pethn_info->is_connect=ms_false;
							break;
						case 1:
							if(ms_false==pethn_info->is_connect){
								ms_s08 strCurDTime[64]={0};
								ms_strcpy(pethn_info->time_string, mstime_api_curDTime(mstime_fmt_datetime,strCurDTime));
							}
							pethn_info->is_connect=ms_true;
							break;
					}
				}
			}
		}
		ms_sleep(1);
	}
}
ms_void * mspppoe_innerapi_recovery(ms_void * arglist)
{
	msthread_api_setName("pppoeRecovery");
	ms_u08   connect_num=0;
	ms_u08   needcnect_num=0;
	ms_u08   nonor=0;
	while (1){
		ms_sleep(30);
		connect_num=0;
		needcnect_num=0;
		if(ms_true==ethnppp_ctt.init){
			if(ms_true==ethnppp_ctt_db.init){
				char eth_index=0;
				for(eth_index=0;eth_index<MAXNUM_ETH;eth_index++){
					ETHNInfo *pethn_info=&ethnppp_ctt.ethn_info[eth_index];
					ETHNInfo *pethndb_info=&ethnppp_ctt_db.ethn_info[eth_index];
					if(ms_buflen(pethndb_info->pppoe_param.ethn_name)>0
						&(ms_true==pethndb_info->is_setup)
						&(ms_true==pethndb_info->is_connect)){
						ms_bool ret=mspppoe_innerapi_check(pethndb_info);
						ms_verbose("[deman]pethndb_info:%s:----mspppoe_innerapi_check:%s,pethn_info:is_connect:%d",
							pethndb_info->pppoe_param.ethn_name,(ms_false==ret) ? "no" : "yes",pethn_info->is_connect);
						if((ms_false==ret)
							||(ms_false==pethn_info->is_connect)){
								ms_byte cmdbuf[256]={0};
								ms_cmd(cmdbuf,"%s %s",mspppoe_stop,pethndb_info->pppoe_param.ethn_name);
								ms_cmd(cmdbuf,"%s %s",mspppoe_start,pethndb_info->pppoe_param.ethn_name);
								needcnect_num+=1;
						}else{
							connect_num+=1;
						}
					}
				}
			}
#if 0		//disable  ppp kill-error
			if(((0==needcnect_num)&&ms_moreThan(mspppoe_innerapi_pppNum(),(connect_num+needcnect_num)))
				||((0!=needcnect_num)&&ms_noLess(mspppoe_innerapi_pppNum(),(connect_num+needcnect_num)))
			){
				if((++nonor)>1){
					ms_waring("mspppoe is wrong,recovery it,(connect_num,needcnect_num,mspppoe_innerapi_pppNum--%d-%d_%d)",
						connect_num,needcnect_num,mspppoe_innerapi_pppNum());
					mspppoe_innerapi_envClear();
					nonor=0;
				}
			}else{
				nonor=0;
			}
#endif
		}
	}
}
ETHNInfo *mspppoe_api_matchEthn(ms_string ms_in ethn_name,ETHPPPContext * ms_in pethnppp_ctt)
{
	ms_pamcheckRet( ms_null,ethn_name, "ethn_name");
	if(ms_false==pethnppp_ctt->init){
		ms_errRet(ms_null,"Please call mspppoe_api_init() function to init pppoe at first");
	}
	ms_u08 eth_index=0;
	for(eth_index=0;eth_index<MAXNUM_ETH;eth_index++){
		ETHNInfo *pethn_info=&pethnppp_ctt->ethn_info[eth_index];
		if(ms_strncmp_saeq(pethn_info->pppoe_param.ethn_name, ethn_name)){
			return pethn_info;
		}
	}
	return ms_null;
}
ms_void mspppoe_api_writeDB(ms_void)
{
	ETHPPPContext *pethnppp_ctt=&ethnppp_ctt;
	cJSON * json_root = cJSON_CreateObject();
	if(ms_null == json_root){
		ms_errNoret("cJSON_CreateObject failed");
	}
	cJSON * json_mspppoeinfo_array = cJSON_CreateArray();
	cJSON_AddItemToObject(json_root, "mspppoeinfo", json_mspppoeinfo_array);
	ms_u32 eth_index=0;
	for(eth_index=0;eth_index<MAXNUM_ETH;eth_index++){
		cJSON * json_mspppoeinfo=cJSON_CreateObject();
		cJSON_AddItemToArray(json_mspppoeinfo_array,json_mspppoeinfo);	
		ETHNInfo *pethn_info=&pethnppp_ctt->ethn_info[eth_index];
		MSJSON_BUILD_STRING(json_mspppoeinfo, "ethn_name", pethn_info->pppoe_param.ethn_name);
		MSJSON_BUILD_STRING(json_mspppoeinfo, "username", pethn_info->pppoe_param.username);
		MSJSON_BUILD_STRING(json_mspppoeinfo, "userpasswd", pethn_info->pppoe_param.userpasswd);
		MSJSON_BUILD_STRING(json_mspppoeinfo, "demond", pethn_info->pppoe_param.demond);
		MSJSON_BUILD_STRING(json_mspppoeinfo, "firewall", pethn_info->pppoe_param.firewall);
		MSJSON_BUILD_STRING(json_mspppoeinfo, "dns1", pethn_info->pppoe_param.dns1);
		MSJSON_BUILD_STRING(json_mspppoeinfo, "dns2", pethn_info->pppoe_param.dns2);
		cJSON_AddNumberToObject(json_mspppoeinfo, "is_setup", pethn_info->is_setup);
		cJSON_AddNumberToObject(json_mspppoeinfo, "is_connect", pethn_info->is_connect);
		MSJSON_BUILD_STRING(json_mspppoeinfo, "ipaddr_testing", pethn_info->ipaddr_testing);
	}	

	char * json_string = cJSON_Print(json_root);
	cJSON_Delete(json_root);
	if(ms_null==json_string){
		ms_errNoret("cJSON_Print failed");
	}
	
	msmd_api_writeProtect(ms_dbmspppoe, json_string, strlen(json_string));
ms_end:	
	free(json_string);
}

ms_void mspppoe_api_init(ms_void)
{
	if(ms_false==pnetcard_info->isinit){
		ms_errNoret("Init pnetcard_info first");
	}
	ms_system("mkdir -p /etc/mscore/db/");
	ms_buf0(&ethnppp_ctt);
	ms_buf0(&ethnppp_ctt_db);
	if(!(mspppoe_innerapi_readDB(&ethnppp_ctt)<0)){	//maybe there's no pppoe_db file
		ms_debug("recovry pppoe ...");
		ms_memcpy(&ethnppp_ctt_db,&ethnppp_ctt,sizeof(ETHPPPContext));
		mspppoe_innerapi_envClear();
		mspppoe_innerapi_recovrystart();
	}else{
		mspppoe_innerapi_envClear();
	}
	ethnppp_ctt.init=ms_true;
	ethnppp_ctt_db.init=ms_true;
	msthread_api_create(&mspppoemonitor_ctt.msst_pppupdate,    "mspppope_update", mspppoe_innerapi_update, (ms_void *) ms_null);
	msthread_api_create(&mspppoemonitor_ctt.msst_ppprecovery, "mspppope_recovery", mspppoe_innerapi_recovery, (ms_void *) ms_null);
}

ms_void mspppoe_api_deinit(ms_void)
{
	ethnppp_ctt.init=ms_false;
	ethnppp_ctt_db.init=ms_false;
	msthread_api_destroy(&mspppoemonitor_ctt.msst_pppupdate);
	msthread_api_destroy(&mspppoemonitor_ctt.msst_ppprecovery);
}
//$1 ethn username userpasswd [demond] [firewall] [dns1] [dns2]
ms_s32 mspppoe_api_setup(PPPOEParam ms_in pppoe_param)
{
	if(ms_false==ethnppp_ctt.init){
		ms_errRet(mctuerr_pppoe_noinit,"Please init ethnppp_ctt val at first,call mspppoe_api_init()");
	}

	ms_verbose("Get valid eth....");
	ETHNInfo*pethn_info=mspppoe_innerapi_getValidEthn(pppoe_param.ethn_name,&ethnppp_ctt);
	if(ms_null==pethn_info){
		ms_errRet(mctuerr_pppoe_noethn,"No found the interface(%s)",pppoe_param.ethn_name);
	}
	
	ms_byte cmdbuf[2048]={0};
	ms_sprintfs(cmdbuf,"%s %s %s %s %s %s %s %s %s",
		mspppoe_setup,
		pppoe_param.ethn_name,
		pppoe_param.username,
		pppoe_param.userpasswd,
		pppoe_param.debug,
		pppoe_param.demond,
		pppoe_param.firewall,
		pppoe_param.dns1,
		pppoe_param.dns2);
	ms_verbose("cmdbuf:%s",cmdbuf);
	if(ms_false==ms_cmdRet(cmdbuf)){
		ms_errRet(mctuerr_pppoe_cmdfail,"[%s]cmd(%s) failed",pppoe_param.ethn_name,cmdbuf);
	}
	ms_memcpy(&pethn_info->pppoe_param, &pppoe_param,sizeof(PPPOEParam));
	pethn_info->is_setup=ms_true;

	
	ETHNInfo*pethn_info_fb=mspppoe_innerapi_getValidEthn(pppoe_param.ethn_name,&ethnppp_ctt_db);
	if(ms_null==pethn_info_fb){
		ms_errRet(mctuerr_pppoe_noethn,"No found the interface(%s)",pppoe_param.ethn_name);
	}
	ms_memcpy(&pethn_info_fb->pppoe_param, &pppoe_param,sizeof(PPPOEParam));
	pethn_info_fb->is_setup=ms_true;
	return 0;
}
ms_s32 mspppoe_api_start(ms_string ms_in ethn_name)
{
	ms_pamcheckRet( mctuerr_pppoe_paramerror,ethn_name, "ethn_name");
	if(ms_false==ethnppp_ctt.init){
		ms_errRet(mctuerr_pppoe_noinit,"Please call mspppoe_api_init() function to init pppoe at first");
	}
	mspppoe_api_stop(ethn_name);
	ETHNInfo*pethn_info=mspppoe_api_matchEthn(ethn_name,&ethnppp_ctt);
	ms_bufcheckRetDes(mctuerr_pppoe_noethn, pethn_info,"[%s]No valid ethn info,must be setup first",ethn_name);
	
	if(ms_false==pethn_info->is_setup){
		ms_errRet(mctuerr_pppoe_nosetup,"[%s]Must be setup first",ethn_name);
	}
	
	if(ms_false==pethn_info->is_connect){	
		ms_byte cmdbuf[256]={0};
		ms_sprintfs(cmdbuf,"%s %s",mspppoe_start,ethn_name);
		ms_verbose("cmdbuf:%s",cmdbuf);
		if(ms_false==ms_cmdRet(cmdbuf)){
			//有可能由于超时过长，已经生成拨号，导致指令一直错误的问题
			//ms_errRet(mctuerr_pppoe_cmdfail,"[%s]cmd(%s) failed",ethn_name,cmdbuf);
		}
	}else{
		ms_waring("[%s] no need to start",ethn_name);
	}
	if(1!=mspppoe_innerapi_getPppInfo(pethn_info)){
		pethn_info->is_connect=ms_false;
		ms_errRet(mctuerr_pppoe_cmdfail,"[%s]mspppoe_innerapi_getPppInfo failed",ethn_name);
	}
	pethn_info->is_connect=ms_true;
	ms_s08 strCurDTime[64]={0};
	ms_strcpy(pethn_info->time_string, mstime_api_curDTime(mstime_fmt_datetime,strCurDTime));
	
	ETHNInfo*pethn_info_fb=mspppoe_api_matchEthn(ethn_name,&ethnppp_ctt_db);
	ms_bufcheckRetDes(mctuerr_pppoe_noethn, pethn_info_fb,"[%s]No valid ethn info,must be setup first",ethn_name);
	pethn_info_fb->is_connect=ms_true;
	mspppoe_innerapi_updateFlag(ethn_name,ms_true);
	return 0;
}

ms_s32 mspppoe_api_stop(ms_string ms_in ethn_name)
{
	ms_pamcheckRet( mctuerr_pppoe_paramerror,ethn_name, "ethn_name");
	if(ms_false==ethnppp_ctt.init){
		ms_errRet(mctuerr_pppoe_noinit,"Please call mspppoe_api_init() function to init pppoe at first");
	}
	ETHNInfo*pethn_info=mspppoe_api_matchEthn(ethn_name,&ethnppp_ctt);
	ms_bufcheckRetDes(mctuerr_pppoe_noethn, pethn_info,"[%s]No find the ethn info",ethn_name);

	if(ms_true==pethn_info->is_connect){
		ms_byte cmdbuf[256]={0};
		ms_sprintfs(cmdbuf,"%s %s",mspppoe_stop,ethn_name);
		ms_verbose("cmdbuf:%s",cmdbuf);
		if(ms_false==ms_cmdRet(cmdbuf)){
			mspppoe_innerapi_rmPidFile(ethn_name);
			ms_errRet(mctuerr_pppoe_cmdfail,"[%s]cmd(%s) failed",ethn_name,cmdbuf);
		}
		ms_memset(&pethn_info->ppp_info,0,sizeof(PPPInfo));
	}else{
		ms_waring("[%s] no need to stop",ethn_name);
	}
	pethn_info->is_connect=ms_false;
	ms_buf0(pethn_info->time_string);
	
	ETHNInfo*pethn_info_fb=mspppoe_api_matchEthn(ethn_name,&ethnppp_ctt_db);
	ms_bufcheckRetDes(mctuerr_pppoe_noethn, pethn_info_fb,"[%s]No valid ethn info,must be setup first",ethn_name);
	pethn_info_fb->is_connect=ms_false;
	mspppoe_innerapi_updateFlag(ethn_name,ms_false);
	return 0;
}
#undef MSPPPOE_C
